package  
{
  import flash.display.*;
  import flash.events.*;
  import flash.media.*;
  import flash.net.*;
  import flash.text.*;
  import flash.system.*;
  
  import flash.net.NetConnection;
  import flash.net.NetStream;
  
  import flash.geom.ColorTransform;
  
  import flash.filters.DropShadowFilter;
  import flash.utils.Timer;
  import flash.external.ExternalInterface;
  import flash.geom.Rectangle;
  
  import htmlelements.IMediaElement;
  import htmlelements.AudioElement;
  
  public class FlashMediaElement extends MovieClip {

    private var _mediaUrl:String;
    private var _autoplay:Boolean;
    private var _preload:String;
    private var _timerRate:Number;
    private var _stageWidth:Number;
    private var _stageHeight:Number;
    private var _startVolume:Number;
    private var _controlStyle:String;
    private var _streamer:String = "";

    // Media
    private var _mediaElement:IMediaElement;
    
    // Security Checks
    private var securityIssue:Boolean = false; // When SWF parameters contain illegal characters
    private var directAccess:Boolean = false; // When SWF visited directly with no parameters (or when security issue detected)    


    public function FlashMediaElement():void {

      // Allow this player to be called from a different domain than the HTML page hosting the player
      Security.allowDomain("*");
      
      // Check for security issues
      checkFlashVars(loaderInfo.parameters);     

      if (securityIssue) {
        return;
      }
        
      // Get Parameters
      var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
      _mediaUrl = (params['file'] != undefined) ? String(params['file']) : "";
      _autoplay = (params['autoplay'] != undefined) ? (String(params['autoplay']) == "true") : false;
      _timerRate = (params['timerrate'] != undefined) ? (parseInt(params['timerrate'], 10)) : 250;
      _startVolume = (params['startvolume'] != undefined) ? (parseFloat(params['startvolume'])) : 0.8;
      _preload = (params['preload'] != undefined) ? params['preload'] : "none";
      _controlStyle = (params['controlstyle'] != undefined) ? (String(params['controlstyle'])) : ""; // blank or "floating"
      _streamer = (params['flashstreamer'] != undefined) ? (String(params['flashstreamer'])) : "";
      
      if (isNaN(_timerRate))
        _timerRate = 250;

      // Setup player stage
      stage.align = StageAlign.TOP_LEFT;
      stage.scaleMode = StageScaleMode.NO_SCALE;
      _stageWidth = stage.stageWidth;
      _stageHeight = stage.stageHeight;
      stage.addChild(this);
      

      // Create media element
      _mediaElement = new AudioElement(this, _autoplay, _preload, _timerRate, _startVolume);

      if (_mediaUrl != "") {
        _mediaElement.setSrc(_mediaUrl);
      }      

      if (ExternalInterface.available) {

        try {
          if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") {
            
            // Add HTML media methods
            ExternalInterface.addCallback("playMedia", playMedia);
            ExternalInterface.addCallback("loadMedia", loadMedia);
            ExternalInterface.addCallback("pauseMedia", pauseMedia);
            ExternalInterface.addCallback("stopMedia", stopMedia);
  
            ExternalInterface.addCallback("setSrc", setSrc);
            ExternalInterface.addCallback("setCurrentTime", setCurrentTime);
            ExternalInterface.addCallback("setVolume", setVolume);
            ExternalInterface.addCallback("setMuted", setMuted);
  
            // Fire init method          
            ExternalInterface.call("mejs.MediaPluginBridge.initPlugin", ExternalInterface.objectID);
          }


        } catch (error:SecurityError) {
        } catch (error:Error) {
        }

      }

      if (_preload != "none") {
        _mediaElement.load();
        
        if (_autoplay) {
          _mediaElement.play();
        }
      } else if (_autoplay) {
        _mediaElement.load();
        _mediaElement.play();
      }

      // Send click events up to javascript
      stage.addEventListener(MouseEvent.CLICK, stageClicked);
    }
        
    private function checkFlashVars(p:Object):void {
      var i:Number = 0;
      for (var s:String in p) {
        if (isIllegalChar(p[s], s === 'file')) {
          securityIssue = true; // Illegal char found
        }
        i++;
      }
      if(i === 0 || securityIssue) {
        directAccess = true;
      }
    }

    private function isIllegalChar(s:String, isUrl:Boolean):Boolean {
      var illegals:String = "' \" ( ) { } * + \\ < >";
      if(isUrl) {
        illegals = "\" { } \\ < >";
      }
      if(Boolean(s)) { // Otherwise exception if parameter null.
        for each (var illegal:String in illegals.split(' ')) {
          if(s.indexOf(illegal) >= 0) {
            return true; // Illegal char found
          }
        }
      }
      return false;
    }        
        
        
    // START: Controls & Events

    public function stageClicked(e:MouseEvent):void {
      if (e.target == stage) {
        sendEvent("click", "");
      }
    }

    // END: Controls & Events

    // START: External Interface 

    public function playMedia():void {
      _mediaElement.play();
    }

    public function loadMedia():void {
      _mediaElement.load();
    }

    public function pauseMedia():void {
      _mediaElement.pause();
    }

    public function setSrc(url:String):void {
      _mediaElement.setSrc(url);
    }

    public function stopMedia():void {
      _mediaElement.stop();
    }

    public function setCurrentTime(time:Number):void {
      _mediaElement.setCurrentTime(time);
    }

    public function setVolume(volume:Number):void {
      _mediaElement.setVolume(volume);
    }

    public function setMuted(muted:Boolean):void {
      _mediaElement.setMuted(muted);
    } 
    
    // END: External Interface

    // SEND events to JavaScript
    public function sendEvent(eventName:String, eventValues:String):void {
      
      if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") {
        
        if (eventValues == null)
          eventValues == "";

        eventValues = "{" + eventValues + "}";       
        
        // Use set timeout for performance reasons
        ExternalInterface.call("setTimeout", "mejs.MediaPluginBridge.fireEvent('" + ExternalInterface.objectID + "','" + eventName + "'," + eventValues + ")",0);
      }
    }
  }
}
